Unik pameti v TClientDataSet (libmidas) v Kylix
Otázka od: Slezak Jan
7. 11. 2003 13:55
Omlouvam se pokud se zde toto tema jiz resilo, ale zadny takovy prispevek
jsem nenasel.
Mam nasledujici problem: pouzivam na linuxu TClientDataSet jako lokalni
databazi, v rezimu kdy ji casto oteviram a zaviram, pripadne vymenuji cds
soubor nad kterym operuje. V tomto rezimu dochazi k postupnemu a totalnimu
spotrebovani veskere dostupne pameti az do zamrznuti celeho systemu.
Uvitam jakoukoliv radu, jak problem odstranit, ale take jen zpravu, ze nize
uvedena dema nekomu z Vas funguji bez uniku pameti. Problem je pro me
naprosto fatalni, protoze nelze nijak obejit, jde o serverovou aplikaci a
protoze z duvodu portability kodu na Win32 nelze TClientDataSet nahradit.
S pozdravem
Jan Slezak
ELCOM-IPC spol. s r. o.
Problem lze demonstrovat na tomto kodu:
program Project1;
{$APPTYPE CONSOLE}
uses
SysUtils,
DBClient;
var
ClientDataSet1: TClientDataSet;
begin
ClientDataSet1:= TClientDataSet.Create(nil);
ClientDataSet1.FileName:= '/home/slezak/tmp/test.cds';
ClientDataSet1.Open;
repeat
ClientDataSet1.Close;
ClientDataSet1.Open;
Sleep(1);
until False;
end.
Stejny efekt ma spusteni nasledujiciho programu. Nastaveni vlastnosti Data
totiz interne take zavira a otevira TClientDataSet.
program Project2;
{$APPTYPE CONSOLE}
uses
SysUtils,
DBClient;
var
ClientDataSet1: TClientDataSet;
ClientDataSet2: TClientDataSet;
begin
ClientDataSet1:= TClientDataSet.Create(nil);
ClientDataSet2:= TClientDataSet.Create(nil);
ClientDataSet1.FileName:= '/home/slezak/tmp/test.cds';
ClientDataSet1.Open;
repeat
ClientDataSet2.Data:= ClientDataSet1.Data;
Sleep(1);
until False;
end.
Postupnym rozborem zdrojoveho kodu TClientDataSetu jsem dospel k zaveru, ze
problem zpusobuje primo knihovna libmidas.so.1.0. Lze to demonstrovat timto
kodem:
program Project3;
{$APPTYPE CONSOLE}
uses
Classes,
SysUtils,
VarUtils,
DSIntf;
var
Stream: TFileStream;
Size: Integer;
VarBound: TVarArrayBoundArray;
DataPtr: Pointer;
DataPacket: TDataPacket;
DSBase: IDSBase;
begin
Stream:= TFileStream.Create('/home/slezak/tmp/test.cds', fmOpenRead);
try
Size:= Stream.Size;
FillChar(VarBound, SizeOf(VarBound), 0);
VarBound[0].ElementCount:= Size;
DataPacket:= TDataPacket(SafeArrayCreate(varByte, 1, VarBound));
SafeArrayAccessData(DataPacket, DataPtr);
try
Stream.Read(DataPtr^, Size);
finally
SafeArrayUnAccessData(DataPacket);
end;
finally
Stream.Free;
end;
repeat
CreateDbClientObject(CLSID_DSBase, IDSBase, DSBase);
DSBase.AppendData(DataPacket, True);
DSBase:= nil; // nebo take DSBase._Release;
Sleep(1);
until False;
end.
----------
* www.inMail.sk - Vasa emailova adresa na cely zivot ZDARMA
* Mail neobsahuje virusy. Zkontrolovane antivirusom NOD32 (www.eset.sk)
* www.SlovakNET.sk - profesionalny webhosting, domena .SK ZADARMO
* Zoner Media Explorer 5 - stiahnite si pomocnika pre digitalnu fotografiu
(zme.zoner.sk)